Dados obtidos do site Brasil.io. O qual disponibiliza não apenas os dados como também documentação, diversas visualizações dos dados, uma API de acesso além do código fonte de tudo.

URL direta dos dados: https://brasil.io/dataset/covid19/files/.

Data de download: 02/03/2021.


Carga dos dados.

dados <- read.csv("caso.csv", header = TRUE, stringsAsFactors = FALSE)

Vamos manter apenas os dados dos municípios do estado do Rio de Janeiro e vamos remover colunas que não serão utilizadas: state (é sempre RJ), place_type (é sempre city) e estimated_population_2019 (desatualizada).

Além disso, retirar os Importados/Indefinidos:

dados <- dados[dados$state == "RJ" & dados$place_type == "city", ]
dados <- dados[ , - c(2, 4, 9)] # state, place_type, estimated_population_2019
dados <- dados[dados$city != "Importados/Indefinidos", ]

Buscando padrões - Média 100k Habitantes

Número de mortes por dia:

dados$deaths_day <- 0

municipios <- sort(unique(dados$city))

for (municipio in municipios) {
  indices <- sort(dados[dados$city == municipio, "order_for_place"])
  acumulado <- 0
  for (indice in indices) {
    mortes_no_dia <- dados[dados$city == municipio & dados$order_for_place == indice, "deaths"] - acumulado
    dados[dados$city == municipio & dados$order_for_place == indice, "deaths_day"] <- mortes_no_dia
    acumulado <- dados[dados$city == municipio & dados$order_for_place == indice, "deaths"]
  }
}

Média de mortes por semana:

# seleciona apenas colunas de interesse
temp <- dados[ , c("date", "city", "estimated_population", "deaths_day")]

# todas as datas que existem no conjunto de dados
datas <- sort(unique(temp$date))

linha <- nrow(temp)
for (municipio in municipios) {
  populacao <- unique(temp[temp$city == municipio, "estimated_population"])
  for (data in datas) {
    if (nrow(temp[temp$city == municipio & temp$date == data,]) == 0) {
      linha <- linha + 1
      temp[(linha), "date"] <- data
      temp[(linha), "city"] <- municipio
      temp[(linha), "estimated_population"] <- populacao
      temp[(linha), "deaths_day"] <- 0 
    }
  }
}

temp$week <- 0

datas <- sort(unique(temp$date))

# Para cada data o numero de sua semana
for (municipio in municipios) {
  i <- 0
  for (data in datas) {
    temp[temp$city == municipio & temp$date == data, "week"] <- as.integer(i / 7) + 1
    i <- i + 1
  }
}

# Semanas, cidades e média de mortes de cada semana:
semanal <- data.frame(week = 0, city = "", mean_deaths_week = 0, estimated_population=0, stringsAsFactors = FALSE)

semanas <- sort(unique(temp$week))

i <- 1
for (municipio in municipios) {
  for (semana in semanas) {
    total <- sum(temp[temp$city == municipio & temp$week == semana, "deaths_day"])
    linhas <- nrow(temp[temp$city == municipio & temp$week == semana, ])
    semanal[i, "week"] <- semana
    semanal[i, "city"] <- municipio
    semanal[i, "mean_deaths_week"] <- total / linhas
    i<- i + 1
  }
  semanal[semanal$city == municipio, "estimated_population"] <- unique(temp[temp$city == municipio, "estimated_population"])
}

Dados de Regiões de Saúde do Rio de Janeiro:

regioes_saude <- read.csv("regioes_saude.csv", header = TRUE, stringsAsFactors = FALSE)

semanal <- merge(semanal, regioes_saude, by="city", all.x=TRUE)

Agregando os dados por Regiões de Saúde:

agregado <- aggregate(semanal[ , c("mean_deaths_week", "estimated_population")], by = list(semanal$week, semanal$health_region), FUN = sum)
colnames(agregado) <- c("week", "health_region", "mean_deaths_week", "estimated_population")

Adicionando atributo média de mortes por semana, por 100 mil habitantes:

agregado$mean_deaths_week_100k_inhabitants <- 100000 * agregado$mean_deaths_week / agregado$estimated_population

Utilizando dados agregados no tempo (semanas) e no espaço (regiões de saúde) vamos buscar padrões comparando os gráficos:

Primeiro carregando a biblioteca necessária para os gráficos:

library("ggplot2")

Comparando a região de saúde “Metropolitana I” com as outras:

ggplot(agregado[agregado$health_region %in% c("Metropolitana I", "Baía da Ilha Grande"),], aes(x=week, y=mean_deaths_week_100k_inhabitants, group=health_region)) +
  geom_point(aes(color=health_region)) +
  geom_line(aes(color=health_region), show.legend = FALSE) +
  labs(x = "semana", y = "mortes/semana 100k habitantes") +
  theme(legend.position="bottom", panel.background = element_blank(), axis.line = element_line(colour = "black"))


ggplot(agregado[agregado$health_region %in% c("Metropolitana I", "Baixada Litorânea" ),], aes(x=week, y=mean_deaths_week_100k_inhabitants, group=health_region)) +
  geom_point(aes(color=health_region)) +
  geom_line(aes(color=health_region), show.legend = FALSE) +
  labs(x = "semana", y = "mortes/semana 100k habitantes") +
  theme(legend.position="bottom", panel.background = element_blank(), axis.line = element_line(colour = "black")) 


ggplot(agregado[agregado$health_region %in% c("Metropolitana I", "Centro-Sul"),], aes(x=week, y=mean_deaths_week_100k_inhabitants, group=health_region)) +
  geom_point(aes(color=health_region)) +
  geom_line(aes(color=health_region), show.legend = FALSE) +
  labs(x = "semana", y = "mortes/semana 100k habitantes") +
  theme(legend.position="bottom", panel.background = element_blank(), axis.line = element_line(colour = "black"))


ggplot(agregado[agregado$health_region %in% c("Metropolitana I", "Médio Paraíba" ),], aes(x=week, y=mean_deaths_week_100k_inhabitants, group=health_region)) +
  geom_point(aes(color=health_region)) +
  geom_line(aes(color=health_region), show.legend = FALSE) +
  labs(x = "semana", y = "mortes/semana 100k habitantes") +
  theme(legend.position="bottom", panel.background = element_blank(), axis.line = element_line(colour = "black")) 


ggplot(agregado[agregado$health_region %in% c("Metropolitana I", "Metropolitana II" ),], aes(x=week, y=mean_deaths_week_100k_inhabitants, group=health_region)) +
  geom_point(aes(color=health_region)) +
  geom_line(aes(color=health_region), show.legend = FALSE) +
  labs(x = "semana", y = "mortes/semana 100k habitantes") +
  theme(legend.position="bottom", panel.background = element_blank(), axis.line = element_line(colour = "black")) 


ggplot(agregado[agregado$health_region %in% c("Metropolitana I", "Noroeste"),], aes(x=week, y=mean_deaths_week_100k_inhabitants, group=health_region)) +
  geom_point(aes(color=health_region)) +
  geom_line(aes(color=health_region), show.legend = FALSE) +
  labs(x = "semana", y = "mortes/semana 100k habitantes") +
  theme(legend.position="bottom", panel.background = element_blank(), axis.line = element_line(colour = "black")) 


ggplot(agregado[agregado$health_region %in% c("Metropolitana I", "Norte"),], aes(x=week, y=mean_deaths_week_100k_inhabitants, group=health_region)) +
  geom_point(aes(color=health_region)) +
  geom_line(aes(color=health_region), show.legend = FALSE) +
  labs(x = "semana", y = "mortes/semana 100k habitantes") +
  theme(legend.position="bottom", panel.background = element_blank(), axis.line = element_line(colour = "black")) 


ggplot(agregado[agregado$health_region %in% c("Metropolitana I", "Serrana"),], aes(x=week, y=mean_deaths_week_100k_inhabitants, group=health_region)) +
  geom_point(aes(color=health_region)) +
  geom_line(aes(color=health_region), show.legend = FALSE) +
  labs(x = "semana", y = "mortes/semana 100k habitantes") +
  theme(legend.position="bottom", panel.background = element_blank(), axis.line = element_line(colour = "black")) 

Buscando padrões - Variação Percentual da Média (duas semanas)

Calculando a variação percentual:

agregado$percentage_change <- 0

regioes <- sort(unique(agregado$health_region))
semanas <- sort(unique(agregado$week))

for (regiao in regioes) {
  ultimas_semanas <- c(0, 0, 0)
  
  for (semana in semanas) {
    esta_semana <- agregado[agregado$health_region == regiao & agregado$week == semana, "mean_deaths_week"]
    ultimas_semanas[semana %% 3 + 1] <- esta_semana
    
    mudanca_percentual <- 0
    if (esta_semana != 0) {
      if (semana > 3) {
        mudanca_percentual <- esta_semana / ultimas_semanas[(semana + 1) %% 3 + 1] - 1
      } else {
        mudanca_percentual <- esta_semana / ultimas_semanas[2] - 1
      }
      
      if (is.infinite(mudanca_percentual)) {  # divisao por zero (Inf)?
        mudanca_percentual <- 1
        if (esta_semana < 0) {
          mudanca_percentual <- -1
        }
      }
    }
    agregado[agregado$health_region == regiao & agregado$week == semana, "percentage_change"] <- mudanca_percentual
    
  }
}

Comparação entre as regiões tomando como base a região Metropolitana I:

ggplot(agregado[agregado$health_region %in% c("Metropolitana I", "Baía da Ilha Grande"),], aes(x=week, y=percentage_change, group=health_region)) +
  geom_point(aes(color=health_region)) +
  geom_line(aes(color=health_region), show.legend = FALSE) +
  labs(x = "semana", y = "mortes/semana % (2 semanas)") +
  theme(legend.position="bottom", panel.background = element_blank(), axis.line = element_line(colour = "black"))


ggplot(agregado[agregado$health_region %in% c("Metropolitana I", "Baixada Litorânea" ),], aes(x=week, y=percentage_change, group=health_region)) +
  geom_point(aes(color=health_region)) +
  geom_line(aes(color=health_region), show.legend = FALSE) +
  labs(x = "semana", y = "mortes/semana % (2 semanas)") +
  theme(legend.position="bottom", panel.background = element_blank(), axis.line = element_line(colour = "black")) 


ggplot(agregado[agregado$health_region %in% c("Metropolitana I", "Centro-Sul"),], aes(x=week, y=percentage_change, group=health_region)) +
  geom_point(aes(color=health_region)) +
  geom_line(aes(color=health_region), show.legend = FALSE) +
  labs(x = "semana", y = "mortes/semana % (2 semanas)") +
  theme(legend.position="bottom", panel.background = element_blank(), axis.line = element_line(colour = "black"))


ggplot(agregado[agregado$health_region %in% c("Metropolitana I", "Médio Paraíba" ),], aes(x=week, y=percentage_change, group=health_region)) +
  geom_point(aes(color=health_region)) +
  geom_line(aes(color=health_region), show.legend = FALSE) +
  labs(x = "semana", y = "mortes/semana % (2 semanas)") +
  theme(legend.position="bottom", panel.background = element_blank(), axis.line = element_line(colour = "black")) 


ggplot(agregado[agregado$health_region %in% c("Metropolitana I", "Metropolitana II" ),], aes(x=week, y=percentage_change, group=health_region)) +
  geom_point(aes(color=health_region)) +
  geom_line(aes(color=health_region), show.legend = FALSE) +
  labs(x = "semana", y = "mortes/semana % (2 semanas)") +
  theme(legend.position="bottom", panel.background = element_blank(), axis.line = element_line(colour = "black")) 


ggplot(agregado[agregado$health_region %in% c("Metropolitana I", "Noroeste"),], aes(x=week, y=percentage_change, group=health_region)) +
  geom_point(aes(color=health_region)) +
  geom_line(aes(color=health_region), show.legend = FALSE) +
  labs(x = "semana", y = "mortes/semana % (2 semanas)") +
  theme(legend.position="bottom", panel.background = element_blank(), axis.line = element_line(colour = "black")) 


ggplot(agregado[agregado$health_region %in% c("Metropolitana I", "Norte"),], aes(x=week, y=percentage_change, group=health_region)) +
  geom_point(aes(color=health_region)) +
  geom_line(aes(color=health_region), show.legend = FALSE) +
  labs(x = "semana", y = "mortes/semana % (2 semanas)") +
  theme(legend.position="bottom", panel.background = element_blank(), axis.line = element_line(colour = "black")) 


ggplot(agregado[agregado$health_region %in% c("Metropolitana I", "Serrana"),], aes(x=week, y=percentage_change, group=health_region)) +
  geom_point(aes(color=health_region)) +
  geom_line(aes(color=health_region), show.legend = FALSE) +
  labs(x = "semana", y = "mortes/semana % (2 semanas)") +
  theme(legend.position="bottom", panel.background = element_blank(), axis.line = element_line(colour = "black")) 

LS0tCnRpdGxlOiAiRGFkb3MgQ292aWQtMTkiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCkRhZG9zIG9idGlkb3MgZG8gc2l0ZSA8YSBocmVmPSJodHRwczovL2JyYXNpbC5pbyI+QnJhc2lsLmlvPC9hPi4gTyBxdWFsIGRpc3BvbmliaWxpemEgbsOjbyBhcGVuYXMgb3MgZGFkb3MgY29tbyB0YW1iw6ltIGRvY3VtZW50YcOnw6NvLCBkaXZlcnNhcyB2aXN1YWxpemHDp8O1ZXMgZG9zIGRhZG9zLCB1bWEgQVBJIGRlIGFjZXNzbyBhbMOpbSBkbyBjw7NkaWdvIGZvbnRlIGRlIHR1ZG8uCgpVUkwgZGlyZXRhIGRvcyBkYWRvczogPGEgaHJlZj0iaHR0cHM6Ly9icmFzaWwuaW8vZGF0YXNldC9jb3ZpZDE5L2ZpbGVzLyI+aHR0cHM6Ly9icmFzaWwuaW8vZGF0YXNldC9jb3ZpZDE5L2ZpbGVzLzwvYT4uCgpEYXRhIGRlIGRvd25sb2FkOiAwMi8wMy8yMDIxLgoKLS0tCgpDYXJnYSBkb3MgZGFkb3MuCgpgYGB7cn0KZGFkb3MgPC0gcmVhZC5jc3YoImNhc28uY3N2IiwgaGVhZGVyID0gVFJVRSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQpgYGAKClZhbW9zIG1hbnRlciBhcGVuYXMgb3MgZGFkb3MgZG9zIG11bmljw61waW9zIGRvIGVzdGFkbyBkbyBSaW8gZGUgSmFuZWlybyBlIHZhbW9zIHJlbW92ZXIgY29sdW5hcyBxdWUgbsOjbyBzZXLDo28gdXRpbGl6YWRhczogPGk+c3RhdGU8L2k+ICjDqSBzZW1wcmUgPGk+Uko8L2k+KSwgPGk+cGxhY2VfdHlwZTwvaT4gKMOpIHNlbXByZSA8aT5jaXR5PC9pPikgZSA8aT5lc3RpbWF0ZWRfcG9wdWxhdGlvbl8yMDE5PC9pPiAoZGVzYXR1YWxpemFkYSkuCgpBbMOpbSBkaXNzbywgcmV0aXJhciBvcyA8aT5JbXBvcnRhZG9zL0luZGVmaW5pZG9zPC9pPjoKCmBgYHtyfQpkYWRvcyA8LSBkYWRvc1tkYWRvcyRzdGF0ZSA9PSAiUkoiICYgZGFkb3MkcGxhY2VfdHlwZSA9PSAiY2l0eSIsIF0KZGFkb3MgPC0gZGFkb3NbICwgLSBjKDIsIDQsIDkpXSAjIHN0YXRlLCBwbGFjZV90eXBlLCBlc3RpbWF0ZWRfcG9wdWxhdGlvbl8yMDE5CmRhZG9zIDwtIGRhZG9zW2RhZG9zJGNpdHkgIT0gIkltcG9ydGFkb3MvSW5kZWZpbmlkb3MiLCBdCmBgYAoKPGgyPkJ1c2NhbmRvIHBhZHLDtWVzIC0gTcOpZGlhIDEwMGsgSGFiaXRhbnRlczwvaDI+Ck7Dum1lcm8gZGUgbW9ydGVzIHBvciBkaWE6CgpgYGB7cn0KZGFkb3MkZGVhdGhzX2RheSA8LSAwCgptdW5pY2lwaW9zIDwtIHNvcnQodW5pcXVlKGRhZG9zJGNpdHkpKQoKZm9yIChtdW5pY2lwaW8gaW4gbXVuaWNpcGlvcykgewogIGluZGljZXMgPC0gc29ydChkYWRvc1tkYWRvcyRjaXR5ID09IG11bmljaXBpbywgIm9yZGVyX2Zvcl9wbGFjZSJdKQogIGFjdW11bGFkbyA8LSAwCiAgZm9yIChpbmRpY2UgaW4gaW5kaWNlcykgewogICAgbW9ydGVzX25vX2RpYSA8LSBkYWRvc1tkYWRvcyRjaXR5ID09IG11bmljaXBpbyAmIGRhZG9zJG9yZGVyX2Zvcl9wbGFjZSA9PSBpbmRpY2UsICJkZWF0aHMiXSAtIGFjdW11bGFkbwogICAgZGFkb3NbZGFkb3MkY2l0eSA9PSBtdW5pY2lwaW8gJiBkYWRvcyRvcmRlcl9mb3JfcGxhY2UgPT0gaW5kaWNlLCAiZGVhdGhzX2RheSJdIDwtIG1vcnRlc19ub19kaWEKICAgIGFjdW11bGFkbyA8LSBkYWRvc1tkYWRvcyRjaXR5ID09IG11bmljaXBpbyAmIGRhZG9zJG9yZGVyX2Zvcl9wbGFjZSA9PSBpbmRpY2UsICJkZWF0aHMiXQogIH0KfQpgYGAKCk3DqWRpYSBkZSBtb3J0ZXMgcG9yIHNlbWFuYToKCmBgYHtyfQojIHNlbGVjaW9uYSBhcGVuYXMgY29sdW5hcyBkZSBpbnRlcmVzc2UKdGVtcCA8LSBkYWRvc1sgLCBjKCJkYXRlIiwgImNpdHkiLCAiZXN0aW1hdGVkX3BvcHVsYXRpb24iLCAiZGVhdGhzX2RheSIpXQoKIyB0b2RhcyBhcyBkYXRhcyBxdWUgZXhpc3RlbSBubyBjb25qdW50byBkZSBkYWRvcwpkYXRhcyA8LSBzb3J0KHVuaXF1ZSh0ZW1wJGRhdGUpKQoKbGluaGEgPC0gbnJvdyh0ZW1wKQpmb3IgKG11bmljaXBpbyBpbiBtdW5pY2lwaW9zKSB7CiAgcG9wdWxhY2FvIDwtIHVuaXF1ZSh0ZW1wW3RlbXAkY2l0eSA9PSBtdW5pY2lwaW8sICJlc3RpbWF0ZWRfcG9wdWxhdGlvbiJdKQogIGZvciAoZGF0YSBpbiBkYXRhcykgewogICAgaWYgKG5yb3codGVtcFt0ZW1wJGNpdHkgPT0gbXVuaWNpcGlvICYgdGVtcCRkYXRlID09IGRhdGEsXSkgPT0gMCkgewogICAgICBsaW5oYSA8LSBsaW5oYSArIDEKICAgICAgdGVtcFsobGluaGEpLCAiZGF0ZSJdIDwtIGRhdGEKICAgICAgdGVtcFsobGluaGEpLCAiY2l0eSJdIDwtIG11bmljaXBpbwogICAgICB0ZW1wWyhsaW5oYSksICJlc3RpbWF0ZWRfcG9wdWxhdGlvbiJdIDwtIHBvcHVsYWNhbwogICAgICB0ZW1wWyhsaW5oYSksICJkZWF0aHNfZGF5Il0gPC0gMCAKICAgIH0KICB9Cn0KCnRlbXAkd2VlayA8LSAwCgpkYXRhcyA8LSBzb3J0KHVuaXF1ZSh0ZW1wJGRhdGUpKQoKIyBQYXJhIGNhZGEgZGF0YSBvIG51bWVybyBkZSBzdWEgc2VtYW5hCmZvciAobXVuaWNpcGlvIGluIG11bmljaXBpb3MpIHsKICBpIDwtIDAKICBmb3IgKGRhdGEgaW4gZGF0YXMpIHsKICAgIHRlbXBbdGVtcCRjaXR5ID09IG11bmljaXBpbyAmIHRlbXAkZGF0ZSA9PSBkYXRhLCAid2VlayJdIDwtIGFzLmludGVnZXIoaSAvIDcpICsgMQogICAgaSA8LSBpICsgMQogIH0KfQoKIyBTZW1hbmFzLCBjaWRhZGVzIGUgbcOpZGlhIGRlIG1vcnRlcyBkZSBjYWRhIHNlbWFuYToKc2VtYW5hbCA8LSBkYXRhLmZyYW1lKHdlZWsgPSAwLCBjaXR5ID0gIiIsIG1lYW5fZGVhdGhzX3dlZWsgPSAwLCBlc3RpbWF0ZWRfcG9wdWxhdGlvbj0wLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCgpzZW1hbmFzIDwtIHNvcnQodW5pcXVlKHRlbXAkd2VlaykpCgppIDwtIDEKZm9yIChtdW5pY2lwaW8gaW4gbXVuaWNpcGlvcykgewogIGZvciAoc2VtYW5hIGluIHNlbWFuYXMpIHsKICAgIHRvdGFsIDwtIHN1bSh0ZW1wW3RlbXAkY2l0eSA9PSBtdW5pY2lwaW8gJiB0ZW1wJHdlZWsgPT0gc2VtYW5hLCAiZGVhdGhzX2RheSJdKQogICAgbGluaGFzIDwtIG5yb3codGVtcFt0ZW1wJGNpdHkgPT0gbXVuaWNpcGlvICYgdGVtcCR3ZWVrID09IHNlbWFuYSwgXSkKICAgIHNlbWFuYWxbaSwgIndlZWsiXSA8LSBzZW1hbmEKICAgIHNlbWFuYWxbaSwgImNpdHkiXSA8LSBtdW5pY2lwaW8KICAgIHNlbWFuYWxbaSwgIm1lYW5fZGVhdGhzX3dlZWsiXSA8LSB0b3RhbCAvIGxpbmhhcwogICAgaTwtIGkgKyAxCiAgfQogIHNlbWFuYWxbc2VtYW5hbCRjaXR5ID09IG11bmljaXBpbywgImVzdGltYXRlZF9wb3B1bGF0aW9uIl0gPC0gdW5pcXVlKHRlbXBbdGVtcCRjaXR5ID09IG11bmljaXBpbywgImVzdGltYXRlZF9wb3B1bGF0aW9uIl0pCn0KYGBgCgpEYWRvcyBkZSBSZWdpw7VlcyBkZSBTYcO6ZGUgZG8gUmlvIGRlIEphbmVpcm86CjxpbWcgc3JjPSJyZWdpb2VzX3NhdWRlX2hhYml0YW50ZXNfcmoucG5nIiAvPgoKYGBge3J9CnJlZ2lvZXNfc2F1ZGUgPC0gcmVhZC5jc3YoInJlZ2lvZXNfc2F1ZGUuY3N2IiwgaGVhZGVyID0gVFJVRSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQoKc2VtYW5hbCA8LSBtZXJnZShzZW1hbmFsLCByZWdpb2VzX3NhdWRlLCBieT0iY2l0eSIsIGFsbC54PVRSVUUpCmBgYAoKQWdyZWdhbmRvIG9zIGRhZG9zIHBvciBSZWdpw7VlcyBkZSBTYcO6ZGU6CgpgYGB7cn0KYWdyZWdhZG8gPC0gYWdncmVnYXRlKHNlbWFuYWxbICwgYygibWVhbl9kZWF0aHNfd2VlayIsICJlc3RpbWF0ZWRfcG9wdWxhdGlvbiIpXSwgYnkgPSBsaXN0KHNlbWFuYWwkd2Vlaywgc2VtYW5hbCRoZWFsdGhfcmVnaW9uKSwgRlVOID0gc3VtKQpjb2xuYW1lcyhhZ3JlZ2FkbykgPC0gYygid2VlayIsICJoZWFsdGhfcmVnaW9uIiwgIm1lYW5fZGVhdGhzX3dlZWsiLCAiZXN0aW1hdGVkX3BvcHVsYXRpb24iKQpgYGAKCkFkaWNpb25hbmRvIGF0cmlidXRvIG3DqWRpYSBkZSBtb3J0ZXMgcG9yIHNlbWFuYSwgcG9yIDEwMCBtaWwgaGFiaXRhbnRlczoKCmBgYHtyfQphZ3JlZ2FkbyRtZWFuX2RlYXRoc193ZWVrXzEwMGtfaW5oYWJpdGFudHMgPC0gMTAwMDAwICogYWdyZWdhZG8kbWVhbl9kZWF0aHNfd2VlayAvIGFncmVnYWRvJGVzdGltYXRlZF9wb3B1bGF0aW9uCmBgYAoKClV0aWxpemFuZG8gZGFkb3MgYWdyZWdhZG9zIG5vIHRlbXBvIChzZW1hbmFzKSBlIG5vIGVzcGHDp28gKHJlZ2nDtWVzIGRlIHNhw7pkZSkgdmFtb3MgYnVzY2FyIHBhZHLDtWVzIGNvbXBhcmFuZG8gb3MgZ3LDoWZpY29zOgoKUHJpbWVpcm8gY2FycmVnYW5kbyBhIGJpYmxpb3RlY2EgbmVjZXNzw6FyaWEgcGFyYSBvcyBncsOhZmljb3M6CgpgYGB7cn0KbGlicmFyeSgiZ2dwbG90MiIpCmBgYAoKPGg0PkNvbXBhcmFuZG8gYSByZWdpw6NvIGRlIHNhw7pkZSAiTWV0cm9wb2xpdGFuYSBJIiBjb20gYXMgb3V0cmFzOjwvaDQ+CgpgYGB7cn0KZ2dwbG90KGFncmVnYWRvW2FncmVnYWRvJGhlYWx0aF9yZWdpb24gJWluJSBjKCJNZXRyb3BvbGl0YW5hIEkiLCAiQmHDrWEgZGEgSWxoYSBHcmFuZGUiKSxdLCBhZXMoeD13ZWVrLCB5PW1lYW5fZGVhdGhzX3dlZWtfMTAwa19pbmhhYml0YW50cywgZ3JvdXA9aGVhbHRoX3JlZ2lvbikpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1oZWFsdGhfcmVnaW9uKSkgKwogIGdlb21fbGluZShhZXMoY29sb3I9aGVhbHRoX3JlZ2lvbiksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBsYWJzKHggPSAic2VtYW5hIiwgeSA9ICJtb3J0ZXMvc2VtYW5hIDEwMGsgaGFiaXRhbnRlcyIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siKSkKCmdncGxvdChhZ3JlZ2Fkb1thZ3JlZ2FkbyRoZWFsdGhfcmVnaW9uICVpbiUgYygiTWV0cm9wb2xpdGFuYSBJIiwgIkJhaXhhZGEgTGl0b3LDom5lYSIgKSxdLCBhZXMoeD13ZWVrLCB5PW1lYW5fZGVhdGhzX3dlZWtfMTAwa19pbmhhYml0YW50cywgZ3JvdXA9aGVhbHRoX3JlZ2lvbikpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1oZWFsdGhfcmVnaW9uKSkgKwogIGdlb21fbGluZShhZXMoY29sb3I9aGVhbHRoX3JlZ2lvbiksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBsYWJzKHggPSAic2VtYW5hIiwgeSA9ICJtb3J0ZXMvc2VtYW5hIDEwMGsgaGFiaXRhbnRlcyIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siKSkgCgpnZ3Bsb3QoYWdyZWdhZG9bYWdyZWdhZG8kaGVhbHRoX3JlZ2lvbiAlaW4lIGMoIk1ldHJvcG9saXRhbmEgSSIsICJDZW50cm8tU3VsIiksXSwgYWVzKHg9d2VlaywgeT1tZWFuX2RlYXRoc193ZWVrXzEwMGtfaW5oYWJpdGFudHMsIGdyb3VwPWhlYWx0aF9yZWdpb24pKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9aGVhbHRoX3JlZ2lvbikpICsKICBnZW9tX2xpbmUoYWVzKGNvbG9yPWhlYWx0aF9yZWdpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgbGFicyh4ID0gInNlbWFuYSIsIHkgPSAibW9ydGVzL3NlbWFuYSAxMDBrIGhhYml0YW50ZXMiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIikpCgpnZ3Bsb3QoYWdyZWdhZG9bYWdyZWdhZG8kaGVhbHRoX3JlZ2lvbiAlaW4lIGMoIk1ldHJvcG9saXRhbmEgSSIsICJNw6lkaW8gUGFyYcOtYmEiICksXSwgYWVzKHg9d2VlaywgeT1tZWFuX2RlYXRoc193ZWVrXzEwMGtfaW5oYWJpdGFudHMsIGdyb3VwPWhlYWx0aF9yZWdpb24pKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9aGVhbHRoX3JlZ2lvbikpICsKICBnZW9tX2xpbmUoYWVzKGNvbG9yPWhlYWx0aF9yZWdpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgbGFicyh4ID0gInNlbWFuYSIsIHkgPSAibW9ydGVzL3NlbWFuYSAxMDBrIGhhYml0YW50ZXMiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIikpIAoKZ2dwbG90KGFncmVnYWRvW2FncmVnYWRvJGhlYWx0aF9yZWdpb24gJWluJSBjKCJNZXRyb3BvbGl0YW5hIEkiLCAiTWV0cm9wb2xpdGFuYSBJSSIgKSxdLCBhZXMoeD13ZWVrLCB5PW1lYW5fZGVhdGhzX3dlZWtfMTAwa19pbmhhYml0YW50cywgZ3JvdXA9aGVhbHRoX3JlZ2lvbikpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1oZWFsdGhfcmVnaW9uKSkgKwogIGdlb21fbGluZShhZXMoY29sb3I9aGVhbHRoX3JlZ2lvbiksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBsYWJzKHggPSAic2VtYW5hIiwgeSA9ICJtb3J0ZXMvc2VtYW5hIDEwMGsgaGFiaXRhbnRlcyIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siKSkgCgpnZ3Bsb3QoYWdyZWdhZG9bYWdyZWdhZG8kaGVhbHRoX3JlZ2lvbiAlaW4lIGMoIk1ldHJvcG9saXRhbmEgSSIsICJOb3JvZXN0ZSIpLF0sIGFlcyh4PXdlZWssIHk9bWVhbl9kZWF0aHNfd2Vla18xMDBrX2luaGFiaXRhbnRzLCBncm91cD1oZWFsdGhfcmVnaW9uKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yPWhlYWx0aF9yZWdpb24pKSArCiAgZ2VvbV9saW5lKGFlcyhjb2xvcj1oZWFsdGhfcmVnaW9uKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGxhYnMoeCA9ICJzZW1hbmEiLCB5ID0gIm1vcnRlcy9zZW1hbmEgMTAwayBoYWJpdGFudGVzIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpKSAKCmdncGxvdChhZ3JlZ2Fkb1thZ3JlZ2FkbyRoZWFsdGhfcmVnaW9uICVpbiUgYygiTWV0cm9wb2xpdGFuYSBJIiwgIk5vcnRlIiksXSwgYWVzKHg9d2VlaywgeT1tZWFuX2RlYXRoc193ZWVrXzEwMGtfaW5oYWJpdGFudHMsIGdyb3VwPWhlYWx0aF9yZWdpb24pKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9aGVhbHRoX3JlZ2lvbikpICsKICBnZW9tX2xpbmUoYWVzKGNvbG9yPWhlYWx0aF9yZWdpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgbGFicyh4ID0gInNlbWFuYSIsIHkgPSAibW9ydGVzL3NlbWFuYSAxMDBrIGhhYml0YW50ZXMiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIikpIAoKZ2dwbG90KGFncmVnYWRvW2FncmVnYWRvJGhlYWx0aF9yZWdpb24gJWluJSBjKCJNZXRyb3BvbGl0YW5hIEkiLCAiU2VycmFuYSIpLF0sIGFlcyh4PXdlZWssIHk9bWVhbl9kZWF0aHNfd2Vla18xMDBrX2luaGFiaXRhbnRzLCBncm91cD1oZWFsdGhfcmVnaW9uKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yPWhlYWx0aF9yZWdpb24pKSArCiAgZ2VvbV9saW5lKGFlcyhjb2xvcj1oZWFsdGhfcmVnaW9uKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGxhYnMoeCA9ICJzZW1hbmEiLCB5ID0gIm1vcnRlcy9zZW1hbmEgMTAwayBoYWJpdGFudGVzIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpKSAKYGBgCgo8aDM+QnVzY2FuZG8gcGFkcsO1ZXMgLSBWYXJpYcOnw6NvIFBlcmNlbnR1YWwgZGEgTcOpZGlhIChkdWFzIHNlbWFuYXMpPC9oMz4KCkNhbGN1bGFuZG8gYSB2YXJpYcOnw6NvIHBlcmNlbnR1YWw6CgpgYGB7cn0KYWdyZWdhZG8kcGVyY2VudGFnZV9jaGFuZ2UgPC0gMAoKcmVnaW9lcyA8LSBzb3J0KHVuaXF1ZShhZ3JlZ2FkbyRoZWFsdGhfcmVnaW9uKSkKc2VtYW5hcyA8LSBzb3J0KHVuaXF1ZShhZ3JlZ2FkbyR3ZWVrKSkKCmZvciAocmVnaWFvIGluIHJlZ2lvZXMpIHsKICB1bHRpbWFzX3NlbWFuYXMgPC0gYygwLCAwLCAwKQogIAogIGZvciAoc2VtYW5hIGluIHNlbWFuYXMpIHsKICAgIGVzdGFfc2VtYW5hIDwtIGFncmVnYWRvW2FncmVnYWRvJGhlYWx0aF9yZWdpb24gPT0gcmVnaWFvICYgYWdyZWdhZG8kd2VlayA9PSBzZW1hbmEsICJtZWFuX2RlYXRoc193ZWVrIl0KICAgIHVsdGltYXNfc2VtYW5hc1tzZW1hbmEgJSUgMyArIDFdIDwtIGVzdGFfc2VtYW5hCiAgICAKICAgIG11ZGFuY2FfcGVyY2VudHVhbCA8LSAwCiAgICBpZiAoZXN0YV9zZW1hbmEgIT0gMCkgewogICAgICBpZiAoc2VtYW5hID4gMykgewogICAgICAgIG11ZGFuY2FfcGVyY2VudHVhbCA8LSBlc3RhX3NlbWFuYSAvIHVsdGltYXNfc2VtYW5hc1soc2VtYW5hICsgMSkgJSUgMyArIDFdIC0gMQogICAgICB9IGVsc2UgewogICAgICAgIG11ZGFuY2FfcGVyY2VudHVhbCA8LSBlc3RhX3NlbWFuYSAvIHVsdGltYXNfc2VtYW5hc1syXSAtIDEKICAgICAgfQogICAgICAKICAgICAgaWYgKGlzLmluZmluaXRlKG11ZGFuY2FfcGVyY2VudHVhbCkpIHsgICMgZGl2aXNhbyBwb3IgemVybyAoSW5mKT8KICAgICAgICBtdWRhbmNhX3BlcmNlbnR1YWwgPC0gMQogICAgICAgIGlmIChlc3RhX3NlbWFuYSA8IDApIHsKICAgICAgICAgIG11ZGFuY2FfcGVyY2VudHVhbCA8LSAtMQogICAgICAgIH0KICAgICAgfQogICAgfQogICAgYWdyZWdhZG9bYWdyZWdhZG8kaGVhbHRoX3JlZ2lvbiA9PSByZWdpYW8gJiBhZ3JlZ2FkbyR3ZWVrID09IHNlbWFuYSwgInBlcmNlbnRhZ2VfY2hhbmdlIl0gPC0gbXVkYW5jYV9wZXJjZW50dWFsCiAgICAKICB9Cn0KCmBgYAoKQ29tcGFyYcOnw6NvIGVudHJlIGFzIHJlZ2nDtWVzIHRvbWFuZG8gY29tbyBiYXNlIGEgcmVnacOjbyBNZXRyb3BvbGl0YW5hIEk6CgpgYGB7cn0KZ2dwbG90KGFncmVnYWRvW2FncmVnYWRvJGhlYWx0aF9yZWdpb24gJWluJSBjKCJNZXRyb3BvbGl0YW5hIEkiLCAiQmHDrWEgZGEgSWxoYSBHcmFuZGUiKSxdLCBhZXMoeD13ZWVrLCB5PXBlcmNlbnRhZ2VfY2hhbmdlLCBncm91cD1oZWFsdGhfcmVnaW9uKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yPWhlYWx0aF9yZWdpb24pKSArCiAgZ2VvbV9saW5lKGFlcyhjb2xvcj1oZWFsdGhfcmVnaW9uKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGxhYnMoeCA9ICJzZW1hbmEiLCB5ID0gIm1vcnRlcy9zZW1hbmEgJSAoMiBzZW1hbmFzKSIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siKSkKCmdncGxvdChhZ3JlZ2Fkb1thZ3JlZ2FkbyRoZWFsdGhfcmVnaW9uICVpbiUgYygiTWV0cm9wb2xpdGFuYSBJIiwgIkJhaXhhZGEgTGl0b3LDom5lYSIgKSxdLCBhZXMoeD13ZWVrLCB5PXBlcmNlbnRhZ2VfY2hhbmdlLCBncm91cD1oZWFsdGhfcmVnaW9uKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yPWhlYWx0aF9yZWdpb24pKSArCiAgZ2VvbV9saW5lKGFlcyhjb2xvcj1oZWFsdGhfcmVnaW9uKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGxhYnMoeCA9ICJzZW1hbmEiLCB5ID0gIm1vcnRlcy9zZW1hbmEgJSAoMiBzZW1hbmFzKSIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siKSkgCgpnZ3Bsb3QoYWdyZWdhZG9bYWdyZWdhZG8kaGVhbHRoX3JlZ2lvbiAlaW4lIGMoIk1ldHJvcG9saXRhbmEgSSIsICJDZW50cm8tU3VsIiksXSwgYWVzKHg9d2VlaywgeT1wZXJjZW50YWdlX2NoYW5nZSwgZ3JvdXA9aGVhbHRoX3JlZ2lvbikpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1oZWFsdGhfcmVnaW9uKSkgKwogIGdlb21fbGluZShhZXMoY29sb3I9aGVhbHRoX3JlZ2lvbiksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBsYWJzKHggPSAic2VtYW5hIiwgeSA9ICJtb3J0ZXMvc2VtYW5hICUgKDIgc2VtYW5hcykiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIikpCgpnZ3Bsb3QoYWdyZWdhZG9bYWdyZWdhZG8kaGVhbHRoX3JlZ2lvbiAlaW4lIGMoIk1ldHJvcG9saXRhbmEgSSIsICJNw6lkaW8gUGFyYcOtYmEiICksXSwgYWVzKHg9d2VlaywgeT1wZXJjZW50YWdlX2NoYW5nZSwgZ3JvdXA9aGVhbHRoX3JlZ2lvbikpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1oZWFsdGhfcmVnaW9uKSkgKwogIGdlb21fbGluZShhZXMoY29sb3I9aGVhbHRoX3JlZ2lvbiksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBsYWJzKHggPSAic2VtYW5hIiwgeSA9ICJtb3J0ZXMvc2VtYW5hICUgKDIgc2VtYW5hcykiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIikpIAoKZ2dwbG90KGFncmVnYWRvW2FncmVnYWRvJGhlYWx0aF9yZWdpb24gJWluJSBjKCJNZXRyb3BvbGl0YW5hIEkiLCAiTWV0cm9wb2xpdGFuYSBJSSIgKSxdLCBhZXMoeD13ZWVrLCB5PXBlcmNlbnRhZ2VfY2hhbmdlLCBncm91cD1oZWFsdGhfcmVnaW9uKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yPWhlYWx0aF9yZWdpb24pKSArCiAgZ2VvbV9saW5lKGFlcyhjb2xvcj1oZWFsdGhfcmVnaW9uKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogIGxhYnMoeCA9ICJzZW1hbmEiLCB5ID0gIm1vcnRlcy9zZW1hbmEgJSAoMiBzZW1hbmFzKSIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siKSkgCgpnZ3Bsb3QoYWdyZWdhZG9bYWdyZWdhZG8kaGVhbHRoX3JlZ2lvbiAlaW4lIGMoIk1ldHJvcG9saXRhbmEgSSIsICJOb3JvZXN0ZSIpLF0sIGFlcyh4PXdlZWssIHk9cGVyY2VudGFnZV9jaGFuZ2UsIGdyb3VwPWhlYWx0aF9yZWdpb24pKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9aGVhbHRoX3JlZ2lvbikpICsKICBnZW9tX2xpbmUoYWVzKGNvbG9yPWhlYWx0aF9yZWdpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgbGFicyh4ID0gInNlbWFuYSIsIHkgPSAibW9ydGVzL3NlbWFuYSAlICgyIHNlbWFuYXMpIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpKSAKCmdncGxvdChhZ3JlZ2Fkb1thZ3JlZ2FkbyRoZWFsdGhfcmVnaW9uICVpbiUgYygiTWV0cm9wb2xpdGFuYSBJIiwgIk5vcnRlIiksXSwgYWVzKHg9d2VlaywgeT1wZXJjZW50YWdlX2NoYW5nZSwgZ3JvdXA9aGVhbHRoX3JlZ2lvbikpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1oZWFsdGhfcmVnaW9uKSkgKwogIGdlb21fbGluZShhZXMoY29sb3I9aGVhbHRoX3JlZ2lvbiksIHNob3cubGVnZW5kID0gRkFMU0UpICsKICBsYWJzKHggPSAic2VtYW5hIiwgeSA9ICJtb3J0ZXMvc2VtYW5hICUgKDIgc2VtYW5hcykiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIikpIAoKZ2dwbG90KGFncmVnYWRvW2FncmVnYWRvJGhlYWx0aF9yZWdpb24gJWluJSBjKCJNZXRyb3BvbGl0YW5hIEkiLCAiU2VycmFuYSIpLF0sIGFlcyh4PXdlZWssIHk9cGVyY2VudGFnZV9jaGFuZ2UsIGdyb3VwPWhlYWx0aF9yZWdpb24pKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9aGVhbHRoX3JlZ2lvbikpICsKICBnZW9tX2xpbmUoYWVzKGNvbG9yPWhlYWx0aF9yZWdpb24pLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgbGFicyh4ID0gInNlbWFuYSIsIHkgPSAibW9ydGVzL3NlbWFuYSAlICgyIHNlbWFuYXMpIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpKSAKYGBgCgo=